﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Planer.Model.Validators;

namespace Planer.Model
{
    public class PeriodicalActionModel
    {
        static PeriodicalActionModel model = null;

        protected PeriodicalActionModel()
        {            
        }

        public static PeriodicalActionModel GetInstance()
        {
            if (model == null)
            {
                model = new PeriodicalActionModel();
            }

            return model;
        }

        public List<periodical_action> GetPeriodicalActionsByUser(user User)
        {
            List<periodical_action> result = new List<periodical_action>();
            period p = PeriodModel.GetInstance().GetCurrentPeriod();
            var query = from pact in Program.Db.periodical_action
                        .Include("billing")
                        .Include("periodical_action_transanction")
                        where pact.billing.user.id == User.id && pact.is_active == "y" || pact.periodical_action_transanction.Any(x => x.period.id == p.id)
                        select pact;

            result.AddRange(query.ToArray<periodical_action>());

            return result;
        }

        public List<periodical_action> GetPeriodicalActionsByBilling(billing Bill)
        {
            List<periodical_action> result = new List<periodical_action>();
            period p = PeriodModel.GetInstance().GetCurrentPeriod();

            var query = from pact in Program.Db.periodical_action
                        .Include("billing")
                        .Include("action_category")
                        .Include("periodical_action_transanction")
                        where pact.billing.id == Bill.id && pact.is_active == "y" || pact.periodical_action_transanction.Any(x => x.period.id == p.id)
                        select pact;

            result.AddRange(query.ToArray<periodical_action>());

            return result;
        }

        public ModelResult SaveOrUpdatePeriodicalAction(periodical_action act)
        {
            PeriodicalActionValidator validator = new PeriodicalActionValidator();
            validator.Validate(act);
            if (validator.Status == OperationStatusType.ERROR)
            {
                return new ModelResult(validator.Errors);
            }

            if (act.id == 0)
            {
                Program.Db.AddToperiodical_action(act);
                if (PeriodModel.CompareShortDates(DateTime.Now, act.apply_date) >= 0)
                {
                    CommitTransaction(act, act.apply_date);
                }
                                
            }
            Program.Db.SaveChanges();
            return new ModelResult();
        }

        public ModelResult CommitTransaction(periodical_action Action, DateTime date)
        {
            periodical_action_transanction transaction = new periodical_action_transanction()
            {
                create_date = date,
                mustbe_date = date,
                period = PeriodModel.GetInstance().GetCurrentPeriod(),
                periodical_action = Action                
            };
            return BillingModel.GetInstance().MoneyOperation(Action.billing, transaction);
        }

        public string PrettyPeriod(periodical_action action)
        {
            StringBuilder sb = new StringBuilder();
            if (action.years > 0)
            {
                sb.Append(action.years + " ");
                if (action.years == 1)
                {
                    sb.Append("год ");
                }
                else if (action.years > 1 && action.years < 5)
                {
                    sb.Append("года ");
                }
                else
                {
                    sb.Append("лет ");
                }
            }

            int m = (int)(action.months % 10);
            if (m > 0)
            {
                sb.Append(m + " ");
                if (m == 1)
                {
                    if (action.months == 11)
                        sb.Append("месяцев ");
                    else
                        sb.Append("месяц ");
                }
                else if (m > 1 && m < 5)
                {
                    sb.Append("месяца ");
                }
                else
                {
                    sb.Append("месяцев ");
                }
            }

            int d = (int)(action.days % 10);
            if (d > 0)
            {
                sb.Append(d + " ");
                if (d == 1)
                {
                    if (action.days == 1)
                        sb.Append("дней ");
                    else
                        sb.Append("день ");
                }
                else if (d > 1 && d < 5)
                {
                    sb.Append("дня ");
                }
                else
                {
                    sb.Append("дней ");
                }
            }
            return sb.ToString();
        }

        public string PrettyPeriod(allocation action)
        {
            StringBuilder sb = new StringBuilder();
            if (action.years > 0)
            {
                sb.Append(action.years + " ");
                if (action.years == 1)
                {
                    sb.Append("год ");
                }
                else if (action.years > 1 && action.years < 5)
                {
                    sb.Append("года ");
                }
                else
                {
                    sb.Append("лет ");
                }
            }

            int m = (int)(action.months % 10);
            if (m > 0)
            {
                sb.Append(m + " ");
                if (m == 1)
                {
                    if (action.months == 11)
                        sb.Append("месяцев ");
                    else
                        sb.Append("месяц ");
                }
                else if (m > 1 && m < 5)
                {
                    sb.Append("месяца ");
                }
                else
                {
                    sb.Append("месяцев ");
                }
            }

            int d = (int)(action.days % 10);
            if (d > 0)
            {
                sb.Append(d + " ");
                if (d == 1)
                {
                    if (action.days == 1)
                        sb.Append("дней ");
                    else
                        sb.Append("день ");
                }
                else if (d > 1 && d < 5)
                {
                    sb.Append("дня ");
                }
                else
                {
                    sb.Append("дней ");
                }
            }
            return sb.ToString();
        }
    }
}
